package com.twu.biblioteca.controller;

import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import com.twu.biblioteca.entity.Book;
import com.twu.biblioteca.enums.MapKey;
import com.twu.biblioteca.enums.Status;
import com.twu.biblioteca.exception.CheckoutFailException;
import com.twu.biblioteca.exception.ReturnFailException;
import com.twu.biblioteca.model.BookModel;
import com.twu.biblioteca.view.command.Command;

import java.util.List;
import java.util.Map;

@Singleton
public class BookController extends BaseController {
  private BookModel model;

  @Inject
  public BookController(BookModel model) {
    this.model = model;
  }

  public void checkout(Book book) {
    Map<MapKey, Object> objectMap = null;
    try {
      model.checkout(book);
      objectMap = getObjectMapWithTitle(Command.Type.CheckOutBook, Status.Success, book.getTitle());
    } catch (CheckoutFailException cfe) {
      System.out.println(cfe.getMessage());
      objectMap = getObjectMap(Command.Type.CheckOutBook, Status.Failure);
    }
    update(objectMap);
  }

  public void returnBook(String bookTitle) {
    Map<MapKey, Object> objectMap = null;
    try {
      List<Book> checkoutBook = model.getCheckoutBook();
      for (Book b : checkoutBook) {
        if (b.getTitle().equals(bookTitle)) {
          model.returnBook(b);
          update(getObjectMapWithTitle(Command.Type.ReturnBook, Status.Success, b.getTitle()));
          return;
        }
      }
    } catch (ReturnFailException rfe) {
      System.out.println(rfe.getMessage());
    }
    update(getObjectMap(Command.Type.ReturnBook, Status.Failure));
  }

  private Map<MapKey, Object> getObjectMap(Command.Type type, Status status) {
    Map<MapKey, Object> objectMap = Maps.newHashMap();
    objectMap.put(MapKey.Command, type);
    objectMap.put(MapKey.Status, status);
    objectMap.put(MapKey.Books, model.getAvailableBooks());
    return objectMap;
  }

  private Map<MapKey, Object> getObjectMapWithTitle(Command.Type type, Status status,
      String itemTitle) {
    Map<MapKey, Object> objectMap = getObjectMap(type, status);
    objectMap.put(MapKey.ITEM_TITLE, itemTitle);
    return objectMap;
  }

  public void startUpBookLists() {
    update(getObjectMap(Command.Type.StartUp, Status.Success));
  }

  public void bookList() {
    update(getObjectMap(Command.Type.BookList, Status.Success));
  }
}
